package crypt

import (
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
)

// CbcCrypt ...
type CbcCrypt struct {
	key string
}

// SetCryptKey ...
func (c *CbcCrypt) SetCryptKey(key string) error {
	c.key = key
	return nil
}

// ExistCryptKey ...
func (c *CbcCrypt) ExistCryptKey() bool {
	if c.key != "" {
		return true
	}
	return false
}


// Encrypt 加密
func (c *CbcCrypt) Encrypt(data []byte) (string,error) {
	if !c.ExistCryptKey() {
		return "", CryptKeynotFound
	}
	// 转成字节数组
	k := []byte(c.key)
	// 分组秘钥
	// NewCipher该函数限制了输入k的长度必须为16, 24或者32
	block, err := aes.NewCipher(k)
	if err !=nil {
		return "", err
	}
	// 获取秘钥块的长度
	blockSize := block.BlockSize()
	// 补全码
	data = PKCS7Padding(data, blockSize)
	// 加密模式
	blockMode := cipher.NewCBCEncrypter(block, k[:blockSize])
	// 创建数组
	cryted := make([]byte, len(data))
	// 加密
	blockMode.CryptBlocks(cryted, data)
	return base64.StdEncoding.EncodeToString(cryted),nil
}

// Decrypt 解密
func (c *CbcCrypt) Decrypt(data string) (interface{},error) {
	if !c.ExistCryptKey() {
		return nil, CryptKeynotFound
	}
	// 转成字节数组
	crytedByte, err := base64.StdEncoding.DecodeString(data)
	if err !=nil {
		return nil, err
	}
	k := []byte(c.key)
	// 分组秘钥
	block, _ := aes.NewCipher(k)
	// 获取秘钥块的长度
	blockSize := block.BlockSize()
	// 加密模式
	blockMode := cipher.NewCBCDecrypter(block, k[:blockSize])
	// 创建数组
	orig := make([]byte, len(crytedByte))
	// 解密
	blockMode.CryptBlocks(orig, crytedByte)
	// 去补全码
	orig = PKCS7UnPadding(orig)
	return orig,nil
}
